using System;
using System.Collections.Generic;
using System.Text;
using IGlobalist.Cms.Model;
using System.Web;
using System.Xml;
using System.IO;


namespace IGlobalist.Cms.Bll
{
    public class RelationPageCategoryCtr : BaseController
    {
        private static string path = "Admin\\XML\\RelationPageAndCategory.xml";
        private static XmlDocument xDoc;
        private static IList<RelationPageCategoryXML> relations;
        static RelationPageCategoryCtr()
        {
             path = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, path);
        }

        public static RelationPageCategoryXML GetRelationByID(long id){

            XmlNode xNode = GetXmlNodeByID(id);
            return Convert2Relation(xNode);
        }

       

        public static void AddCategory(RelationPageCategoryXML relation, IList<long> subListIDs)
        {
            relation.Categories = new List<long>();
            foreach (long Id in subListIDs)
            {
                if (!relation.Categories.Contains(Id))
                    relation.Categories.Add(Id);
            }
            Update(relation);
        }

        public static void AddCategory(long pageID, IList<long> subListIDs)
        {
            RelationPageCategoryXML rel = GetRelationByID(pageID);
            AddCategory(rel,subListIDs);
        }

        public static void RemoveSub(RelationPageCategoryXML relation, long removeSubID)
        {
            try
            {
                relation.Categories.Remove(removeSubID);
                Update(relation);
            }
            catch (Exception ex)
            {
                Logger.Error("", ex);
            }
            
        }


        
        public static void RemoveSub(long pageID, long removeSubID)
        {
            RelationPageCategoryXML rel = GetRelationByID(pageID);
            try
            {
                rel.Categories.Remove(removeSubID);
                Update(rel);
            }
            catch (Exception ex)
            {
                Logger.Error("", ex);
            }
           
        }

        public static IList<RelationPageCategoryXML> List()
        {
            relations = new List<RelationPageCategoryXML>();
            LoadXML();
            try
            {
                foreach (XmlNode xNode in xDoc.DocumentElement.ChildNodes)
                {
                    RelationPageCategoryXML rel = Convert2Relation(xNode);
                    if (rel != null)
                        relations.Add(rel);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("List category ::", ex);
            }
            return relations;
        }

        public static void Save()
        {
            lock (xDoc)
            {
                xDoc.Save(path);
            }
        }

        public static void Update(RelationPageCategoryXML relation)
        {
            try{
            XmlNode xNode = GetXmlNodeByID(relation.Id);
            xNode.Attributes["name"].Value = relation.Name;
            xNode.Attributes["title"].Value = relation.Title;
            xNode.Attributes["type"].Value = relation.Type.ToString();
            xNode.Attributes["categories"].Value = SubList2StringSub(relation.Categories);            
            Save();
            }catch(Exception ex){
                Logger.Error("",ex);
            }
        }

        public static void Add(RelationPageCategoryXML relation)
        {
            try{
           
            XmlElement xNode = xDoc.CreateElement("Page");
            xNode.SetAttribute("id",relation.Id.ToString());
            xNode.SetAttribute("name", relation.Name);
            xNode.SetAttribute("title", relation.Name);
            xNode.SetAttribute("type", relation.Type.ToString());
            xNode.SetAttribute("categories",SubList2StringSub(relation.Categories)); 
            xDoc.DocumentElement.AppendChild(xNode);
            Save();
            }catch(Exception ex){
                Logger.Error("",ex);
            }
        }

        public static void AddOrUpdate(RelationPageCategoryXML relation)
        {
            try
            {
                RelationPageCategoryXML rel= GetRelationByID(relation.Id);
                if (rel == null)
                    Add(relation);
                else
                    Update(relation);

            }
            catch (Exception ex)
            {
                Logger.Error("", ex);
            }
        }

        public static void Remove(RelationPageCategoryXML relation)
        {   
            try{
                Remove(relation.Id);
            }catch(Exception ex){
                Logger.Error("",ex);
            }
        }

        public static void Remove(long pageID)
        {
            try
            {
                XmlNode xNode = GetXmlNodeByID(pageID);
                if (xNode != null)
                {
                    xDoc.DocumentElement.RemoveChild(xNode);
                    Save();
                    List();
                }
            }
            catch (Exception ex)
            {
                Logger.Error("", ex);
            }
        }

       public static void RemoveAt(int index)
        {
           try{
            RelationPageCategoryXML rel=GetRelationByID(relations[index].Id);
            Remove(rel);
           }catch(Exception ex){
               Logger.Error("",ex);
           }
        }


        

        public int IndexOf(RelationPageCategoryXML relation)
        {
            int index = -1;
            int i = 0;
            foreach (RelationPageCategoryXML rel in relations)
            {
                if (rel.Id == relation.Id)
                {
                    index = i;
                }
                i++;
            }
            return index;
        }

        

        

        #region "Method Member Private"

        private static XmlNode GetXmlNodeByID(long id)
        {
            LoadXML();
            string xpath = String.Format("//Page[@id='{0}']",id);
            XmlNode xNode = xDoc.SelectSingleNode(xpath);
            return xNode;
        }

        

        private static IList<long> StringSub2SubList(string subs){
            
            IList<long> list = new List<long>();

            if (String.IsNullOrEmpty(subs)) return list;
            try
            {
                String[] arrs = subs.Split(',');

                foreach (string id in arrs)
                {
                    try
                    {
                        list.Add(Convert.ToInt64(id.Trim()));
                    }catch{}
                }
            }
            catch (Exception ex)
            {
                Logger.Error("StringSub2SubList", ex);
            }
            return list;
        }

        private static string SubList2StringSub(IList<long> subs)
        {
            string str = "";
            try
            {
                foreach (long id in subs)
                {
                    if (str.Length == 0)
                        str = id.ToString();
                    else
                        str += "," + id.ToString();
                }
            }
            catch (Exception ex)
            {
                Logger.Error("SubList2StringSub", ex);
            }
            return str;
        }

        

        private static RelationPageCategoryXML Convert2Relation(XmlNode xNode)
        {
            RelationPageCategoryXML rel = null; ;
            try{
                rel = new RelationPageCategoryXML(Convert.ToInt64(xNode.Attributes["id"].Value),
                               Convert.ToString(xNode.Attributes["name"].Value),
                               Convert.ToString(xNode.Attributes["title"].Value),
                               Convert.ToByte(xNode.Attributes["type"].Value),                              
                               StringSub2SubList( xNode.Attributes["categories"].Value));
            }
            catch(Exception ex)
            {
                Logger.Error("List XML ", ex);
            }


            return rel;
        }

        private static void LoadXML()
        {
            if (xDoc != null) return;
            xDoc = new XmlDocument();
            lock (xDoc)
            {
                xDoc.Load(path);               
                try
                {
                    HttpContext.Current.Cache.Add("Admin/RelationPageAndCategory.xml", xDoc, new System.Web.Caching.CacheDependency(path), DateTime.Now.AddYears(1), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, new System.Web.Caching.CacheItemRemovedCallback(CacheRemoveCallback));
                }
                catch (Exception e)
                {
                    Logger.Error("Load file " + path, e);
                }
            }
        }

        private static void CacheRemoveCallback(string key, object obj, System.Web.Caching.CacheItemRemovedReason reason)
        {
            xDoc = null;
            LoadXML();
        }
        #endregion
    }
    
}
